/**
 * 当我们new一个构造函数，得到的实例继承了构造器的构造属性(this.name这些)以及原型上的属性。
 * • 创建一个空对象，将它的引用赋给 this，继承函数的原型。
 * • 通过 this 将属性和方法添加至这个对象
 * • 最后返回 this 指向的新对象，也就是实例（如果没有手动返回其他的对象）
 *
 */

function People(name, age) {
  // 1.创建一个新对象，赋予this，这一步是隐性的，let this = {};
  //2.给this指向的对象赋予构造属性
  this.name = name
  this.age = age

  //3.如果没有手动返回对象，则默认返回this指向的这个对象，也是隐性的 return this;
}
People.prototype.sayName = function () {
  console.log('打印名字' + this.name)
}

new People('一二三', 45).sayName()

// 自定义的new方法
function _new(fn, ...arg) {
  // 1.以构造器的prototype属性为原型，创建新对象；
  let obj = Object.create(fn.prototype)
  // 2.将this和调用参数传给构造器执行
  let result = fn.apply(obj, arg) // 为什么要返回result？因为构造函数手动返回了对象，就需要这步操作
  console.log(result) // undefined 因为绑定函数确实没有任何返回，只有当绑定函数有return的时候，才会有返回值。
  // 3.如果构造器没有手动返回对象，则返回第一步的对象
  return result instanceof Object ? result : obj
}

_new(People, '张三').sayName()

